/**
 * 
 */
package xj.toolkit.bean.tlv.decode;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.google.common.base.Preconditions;

/**
 * @author hp
 *
 */
public class DefaultDecoderRepository implements TLVDecoderRepository {

	private Map<Class<?>, TLVDecoder> decoders = new HashMap<Class<?>, TLVDecoder>();

	public void add(Class<?> cls, TLVDecoder decoder) {
		decoders.put(cls, decoder);
	}
	
	public void setDecoders(Collection<TLVDecoder> decoders) {
		Preconditions.checkArgument(decoders != null && decoders.size() > 0);
		
		for (TLVDecoder decoder : decoders) {
			Class<?>[] clazzs = decoder.getFieldType();
			if (null != clazzs && clazzs.length > 0) {
				for (Class<?> clazz : clazzs) {
					add(clazz, decoder);
				}
			}
		}
	}
	
	public Map<Class<?>, TLVDecoder> getDecoders() {
		return Collections.unmodifiableMap( decoders );
	}
	
	/**
	 * @see com.skymobi.bean.tlv.TLVDecoderRepository#getDecoderOf(java.lang.Class)
	 */
	public TLVDecoder getDecoderOf(Class<?> cls) {
		do {
			TLVDecoder decoder = decoders.get(cls);
	        if ( null != decoder ) {
	        	return	decoder;
	        }
	        if ( Object.class.equals(cls) ) {
	        	break;
	        }
	        
	        if ( Object.class.equals(cls.getSuperclass()) ) {
	    		if ( cls.isArray() 
	    			&& Object.class.isAssignableFrom( cls.getComponentType() ) ) {
	    			return	decoders.get(Object[].class);
	    		}
	        }
	        
        	cls = cls.getSuperclass();
        	
		} while ( cls != null );
		
		return	null;
	}

    public Map<String, String> getDecodersAsText() {
    	Map<String, String>	ret = new HashMap<String, String>();
        for (Map.Entry<Class<?>, TLVDecoder> entry : this.decoders.entrySet()) {
        	ret.put(entry.getKey().toString(), entry.getValue().toString());
        }
        
        return	ret;
    }
}
